/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.knolle.validadores;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;


/**
 *
 * @author marcelo
 * 
 * Clase abstracta que encapsula todo lo que debe contener un validador, incluso estoy pensando que deberia de ser un 
 * array con todas las clases de validaciones que se puedan soportar
 *  Validaciones conocidas:
 *      Letras
 *      Enteros Positivos
 *      Enteros 
 *      Decimales Positivos
 *      Decimales
 *      Mails
 *      Expreciones regulares
 * Un icono
 * Un mensaje
 * JDialog que va a mostrar el fondo
 * un Color, que sera el color del panel
 * un padre que sera el objeto que lo contendra
 * un punto que sera el origen
 * y unas dimensiones que establecera que tan grande sera la ventana de alerta
 * 
 */
public abstract class AbstractValidador extends InputVerifier implements KeyListener{
        private Color color;
        private javax.swing.JDialog popup;
        private Object parent;
        private JLabel mensaje;
        private JLabel imagen;
        private Point punto;
        private Dimension comDimension;
        
        
        //Metodo para ser implementado en las clases herederas
        abstract protected Boolean CriterioValidacion(JComponent componente);

        protected void setMensaje(String mensaje){
            this.mensaje.setText(mensaje + " ");
        }
        //Inicializar el color
        private AbstractValidador(){
           color = new Color(243, 255, 159);
        }
        
        //Agregar el Listener al componente, agregar el mensaje, inicializar los demas componentes
        
        private AbstractValidador(JComponent c, String mensaje ){
           this();
           c.addKeyListener(this);
           this.mensaje = new JLabel( mensaje + " ");
           imagen = new JLabel(new ImageIcon(getClass().getResource("/org/knolle/validadores/red_cancel_24x24.png")));          
        }
        
        //Metodo publico para setear los componentes de la clase
        public AbstractValidador(JDialog parent, JComponent c, String mensaje){
            this(c,mensaje);
            this.parent = parent;
            popup = new JDialog(parent);
            initComponent();
        }
        //Metodo para panels
        public AbstractValidador(JPanel parent, JComponent c, String mensaje){
            this(c,mensaje);
            this.parent = parent;
            ;
            popup = new JDialog((JDialog) parent.getParent());
            initComponent();
        }
        
        
        public AbstractValidador(java.awt.Frame parent, JComponent c, String mensaje){
            this(c,mensaje);
            this.parent = parent;
            popup = new JDialog(parent);
            initComponent();
        }
        
        
        private void initComponent(){
            popup.getContentPane().setLayout(new FlowLayout());
            popup.setUndecorated(true);
            popup.getContentPane().setBackground(color);
            popup.getContentPane().add(imagen);
            popup.getContentPane().add(mensaje);
            //Aqui agregar el listener para escuchar cuando se cierra la ventana
            popup.addHierarchyListener(new HierarchyListener() {

            @Override
            public void hierarchyChanged(HierarchyEvent e) {
                System.out.print("Un evento a ocurrido, mostrar: "+e.paramString());
            }
            });
            popup.setFocusableWindowState(false);  
        }
        
        //Asumiendo componentes de SWING
        @Override
        public boolean verify(JComponent c) {
            if (!CriterioValidacion(c)){
                //fallo la verificacion, entonces setear los colores y mostrar el popup                 
                c.setBackground(Color.PINK);
                //Comienza el calculo de las dimensiones del componente
                popup.setSize(0, 0);
                popup.setLocationRelativeTo(c);
                punto = popup.getLocation();
                comDimension = c.getSize();
                popup.setLocation(punto.x-(int)comDimension.getWidth()/2,
                punto.y+(int)comDimension.getHeight()/2);
                popup.pack();
                popup.setVisible(true);
                popup.toFront();
                return false;
             }
             c.setBackground(Color.WHITE);
             return true;
        }

    @Override
    public void keyPressed(KeyEvent e) {
        //Al presionar un tecla el componente oculta el popup
        popup.setVisible(false);
        
    }

    @Override
    public void keyReleased(KeyEvent e) { }

    @Override
    public void keyTyped(KeyEvent e) {}
}
        
        
        
        
